var mariadb = require('mariadb');
var multer  = require('multer');            // cnpm install multer;  通过浏览器上传的文件，其owner为root
var fs=require('fs');

var pbkb={};                                // 定义一个全局的环境变量,避免环境污染
var app_db='pbkb';                          // app_db或者app_name.创建新库/新应用时,第3步,修改此处
pbkb.get_date=function(date){
    var dt,year,mon,day,hour,min,sec;
    if (date){
        dt=new Date(date);
    } else {
        dt=new Date();
    }
    year=dt.getFullYear()+'';
    mon=dt.getMonth()>8 ? (dt.getMonth()+1)+'' : '0' + (dt.getMonth()+1);
    day=dt.getDate()>9 ? dt.getDate()+'' : '0' + dt.getDate();
    hour=dt.getHours()>9 ? dt.getHours()+'' : '0' + dt.getHours();
    min=dt.getMinutes()>9 ? dt.getMinutes()+'' : '0' + dt.getMinutes();
    sec=dt.getSeconds()>9 ? dt.getSeconds()+'' : '0' + dt.getSeconds();
    return year+'-'+mon+'-'+day+'T'+hour+':'+min+':'+sec;
}

mkdir=function(dir){
    if (!fs.existsSync(dir)){               // 文件不存在,则创建 dir 目录
        fs.mkdirSync(dir);
    } else {
        if(!fs.statSync(dir).isDirectory()){
            throw pbkb.get_date() + ' ['+app_db+' error] '+`'${dir}'文件已存在,但不是目录`;
        }
    }
}
rmdir=function(dir){
    if(fs.existsSync(dir)){
        if(fs.statSync(dir).isDirectory()){
            var dir_files=fs.readdirSync(dir);
            for (var i in dir_files){
                fs.unlinkSync(dir+'/'+dir_files[i]);
            }
            fs.rmdirSync(dir);
        }
    }
}
function rename(from,to){
    if(fs.existsSync(from)){
        fs.renameSync(from,to);
    } else {
        pbkb.log('要移动的文件不存在: '+from)
    }
}
function del_attachments(file_id,btime){
    if(btime){                              // 删除普通文件的附件
        var ymd=new Date(btime * 1000);     // year month day
        var year=ymd.getFullYear()+'';
        var mon=ymd.getMonth()>8 ? (ymd.getMonth()+1)+'' : '0' + (ymd.getMonth()+1);
        var day=ymd.getDate()>9 ? ymd.getDate()+'' : '0' + ymd.getDate();
        var attached_full_path=pbkb.attached_path+'/'+year+'/'+mon+day+'/'+file_id;
        rmdir(attached_full_path);
    }
}
function wrong_args(arguments_array,function_name){
    if(Array.isArray(arguments_array) && arguments_array.length>0){    // 参数必须是数组
        for(var i in arguments_array){
            if(typeof(arguments_array[i])==='undefined'){
                pbkb.log('wrong_args of '+function_name);
                return true;
            }
        }
        return false;
    }else{
        pbkb.log('wrong_args of '+function_name);
        return true;
    }
}

pbkb.db_info={
    host:'127.0.0.1',
    user:'admin',
    password:'pbkb',
    port:3306,
    database:app_db,
    //timezone:'Asia/Shanghai',
    connectTimeout:2000,    // 默认值:10000 (10秒)
    compress:false,         // 默认值:false.非局域网环境下,设为true将用gzip压缩,性能更好.
    connectionLimit:1       // 默认值:10. 上面是createConnection的option,这个是createPool的option. 连接后,将产生5个threadId
};

pbkb.pool = mariadb.createPool(pbkb.db_info);   // 以后用 pool.query("call p()").then(rows=>{console.log(rows)}).catch(err=>{console.log(err)});查询
                                                // 经测试pbkb.pool断线后会自动重连
/*
pbkb.log_url=function (req,res,next){
    var req_date=new Date();
    console.log([req_date.toLocaleString(),req.ip,req.method,req.originalUrl].join(' '));
    next();
}*/
pbkb.log=function(str){
    console.log(pbkb.get_date(),'['+app_db+']',str);
}
pbkb.query_err=function (err){
    pbkb.log('数据库出错');
    console.log(err);
//    res.send(err);    // 报错: UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): ReferenceError: res is not defined
}                       // 没有res参数该这么理解:try{}中的语句出错时,http连接就中断了,故res也不复存在了.  .catch()只有一个error参数.

// pbkb系统初始化,创建附件的上传目录
pbkb.pool.query("select value from configuration where name='attached_path' limit 1").then(rows=>{
    if(rows.length){
        pbkb.attached_path=rows[0].value;
        mkdir(pbkb.attached_path);              // 正式文件的目录架构:files/2019/0101/file_id    // 编辑文件时已经有了file_id
    }else{
        pbkb.log('数据库 configuration表 配置出错,退出程序...')
        process.exit(1);
    }
}).catch(pbkb.query_err);
pbkb.pool.query("select value from configuration where name='attached_tmp' limit 1").then(rows=>{
    if(rows.length){
        pbkb.attached_tmp=rows[0].value;
        mkdir(pbkb.attached_tmp);               // 临时文件的目录架构:files_tmp/uid_new          // 一个用户只允许编辑一个文件:uid_new表示用户正在创建新文件或编辑文件
    }else{
        pbkb.log('数据库 configuration表 配置出错,退出程序...')
        process.exit(2);
    }
}).catch(pbkb.query_err);   // 如果不catch,出错时是不是会导致整个node进程退出? 答:不会退出node进程的.

var storage = multer.diskStorage({
    destination: function (req, file, cb){
        mkdir(pbkb.attached_tmp+'/'+req.body.attached_tmp);
        cb(null, pbkb.attached_tmp+'/'+req.body.attached_tmp );     // 返回 文件路径
    },
    filename: function (req, file, cb) {
        cb(null, Date.now() + '_' + file.originalname);             // 返回 文件名
    }
})
pbkb.upload = multer({ storage: storage });
/* 建议增加limits属性,如: upload = multer({ storage: storage, limits: { fieldSize: 1024*2 } });
Key             Description                                                             Default
fieldNameSize   Max field name size                                                     100 bytes
fieldSize       Max field value size (in bytes)                                         1MB
fields          Max number of non-file fields                                           Infinity
fileSize        For multipart forms, the max file size (in bytes)                       Infinity    // 前端能够上传的文件大小由nginx配置文件的client_max_body_size指令决定
files           For multipart forms, the max number of file fields                      Infinity
parts           For multipart forms, the max number of parts (fields + files)           Infinity
headerPairs     For multipart forms, the max number of header key=>value pairs to parse 2000
 */
pbkb.editor_upload=function(req,res){
    var info = {
        "error": 0,
        "url": req.file['path']             // 若是Windows系统,路径分隔符为'\'
    };
    res.send(info);
    pbkb.log('上传了文件: '+info.url);
}
/*  req.file对象有下面8个属性
fieldname: imgFile
originalname: imgerwei.png
encoding: 7bit
mimetype: image/png
destination: files_tmp/1_new
filename: 1579596411861_imgerwei.png        // 当Windows系统上传GBK编码的中文文件名时，浏览器用UTF8编码就会将GBK转换成UTF8的中文
path: files_tmp/1_new/1579596411861_imgerwei.png
size: 326
*/

pbkb.check_cookie=function(req,res){
    var user_id=0,session_id='sid';
    if(Number(req.cookies.user_id)) user_id=Number(req.cookies.user_id);
    if(req.cookies.session_id) session_id=req.cookies.session_id;
    pbkb.log('call check_cookie('+[user_id,session_id].join(',')+')');
    pbkb.pool.query("call check_cookie(?,?)",[user_id,session_id])
    .then(rows=>{
        res.type('json');                       // 若response是text/json,则前端jQuery将rows解析为对象
        res.send(rows[0]);                      // 若response是text/html,则前端jQuery将rows解析为字符串
    })
    .catch(pbkb.query_err);
}
pbkb.del_cookie=function(req,res){
    res.clearCookie('user_id');
    res.clearCookie('session_id');              // 应该做成存储过程,万一攻击者乱传session_id,就把正常用户的session_id都删掉了
    res.send('1');
    pbkb.pool.query("delete from sessions where session_id=?",[req.body.session_id]).then(()=>{
        pbkb.log('用户退出登录(user_id: '+req.body.user_id+'),删除session: '+req.body.session_id);
    }).catch(pbkb.query_err);
}

pbkb.login=function (req,res){
    if(wrong_args([req.body.username,req.body.password,req.body.user_id,req.body.session_id],'login')){
        res.send('wrong_args of login');
    }else{
        pbkb.log('call login('+[req.body.username,req.body.password,req.body.user_id,req.body.session_id].join(',')+')');
        pbkb.pool.query("call login(?,?,?,?)",[req.body.username,req.body.password,req.body.user_id,req.body.session_id])
        .then(rows=>{
            if(rows[0][0].user_id>0){
                res.cookie('user_id',rows[0][0].user_id);          // res.set('Set-Cookie','user_id=1');也可以设置cookie,但res.set()会清除前面重复的header
                res.cookie('session_id',rows[0][0].session_id);    // res.cookie()的第2个参数会进行URI编码
            }
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
};

pbkb.usersinfo=function(req,res){       // 获取用户信息(用户列表)
    if(wrong_args([req.query.uid,req.query.sid],'usersinfo')){
        res.send('wrong_args of usersinfo');
    }else{
        pbkb.pool.query("call usersinfo(?,?)",[req.query.uid,req.query.sid])
        .then(rows=>{
            if(rows[0][0].status){
                res.send('非法用户!');
            }else{
                var response='<table style="border-collapse:collapse;" border="1"><tr><th>user_id</th><th>username</th></tr>';
                for (var i=0;i<rows[0].length;i++){                 // 若使用for(var i in rows[0]),就会将最后的meta:[...]也进行处理
                    response+='<tr><td>'+rows[0][i].user_id+'</td><td>'+rows[0][i].username+'</td></tr>'
                }
                response+='</table>';   // response信息应该由前端处理,减轻后端压力
                res.send(response);
            }
        })
        .catch(pbkb.query_err);
    }
}
pbkb.groupsinfo=function(req,res){      // 获取组信息(组列表)
    if(wrong_args([req.query.uid,req.query.sid],'groupsinfo')){
        res.send('wrong_args of groupsinfo');
    }else{
        pbkb.pool.query("call groupsinfo(?,?)",[req.query.uid,req.query.sid])
        .then(rows=>{
            if(rows[0][0].status){
                res.send('非法用户!');
            }else{
                var response='<table style="border-collapse:collapse;" border="1"><tr><th>group_id</th><th>groupname</th><th>组成员ID</th></tr>';
                for (var i=0;i<rows[0].length;i++){                 // 若使用for(var i in rows[0]),就会将最后的meta:[...]也进行处理
                    response+='<tr><td>'+rows[0][i].group_id+'</td><td>'+rows[0][i].groupname+'</td><td>'+rows[0][i].uids+'</td></tr>'
                }
                response+='</table>';   // response信息应该由前端处理,减轻后端压力
                res.send(response);
            }
        })
        .catch(pbkb.query_err);
    }
}
pbkb.useradd=function(req,res){
    if(wrong_args([req.body.user_id,req.body.session_id,req.body.username,req.body.password],'useradd')){
        res.send('wrong_args of useradd');
    }else{
        pbkb.log('call useradd('+[req.body.user_id,req.body.session_id,req.body.username,req.body.password].join(',')+')');
        pbkb.pool.query("call useradd(?,?,?,?)",[req.body.user_id,req.body.session_id,req.body.username,req.body.password])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}
pbkb.userdel=function(req,res){
    if(wrong_args([req.body.user_id,req.body.session_id,req.body.username],'userdel')){
        res.send('wrong_args of userdel');
    }else{
        pbkb.log('call userdel('+[req.body.user_id,req.body.session_id,req.body.username].join(',')+')');
        pbkb.pool.query("call userdel(?,?,?)",[req.body.user_id,req.body.session_id,req.body.username])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}
pbkb.change_username=function(req,res){
    if(wrong_args([req.body.user_id,req.body.session_id,req.body.username,req.body.new_name],'change_username')){
        res.send('wrong_args of change_username');
    }else{
        pbkb.log('call change_username('+[req.body.user_id,req.body.session_id,req.body.username,req.body.new_name].join(',')+')');
        pbkb.pool.query("call change_username(?,?,?,?)",[req.body.user_id,req.body.session_id,req.body.username,req.body.new_name])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}
pbkb.userquery=function(req,res){
    pbkb.pool.query("select user_id from users where username=? limit 1",[req.body.username])
    .then(rows=>{
        res.type('json');
        res.send(rows);     // 不要res.send(rows[0])的原因:若查询结果为空,rows=[],则rows[0]表示什么都没有,前端$.post()收到空数据,就会触发.fail()函数
    })
    .catch(pbkb.query_err);
}
pbkb.password_reset=function(req,res){
    if(wrong_args([req.body.user_id,req.body.session_id,req.body.username,req.body.password],'password_reset')){
        res.send('wrong_args of password_reset');
    }else{
        pbkb.log('call password_reset('+[req.body.user_id,req.body.session_id,req.body.username,req.body.password].join(',')+')');
        pbkb.pool.query("call password_reset(?,?,?,?)",[req.body.user_id,req.body.session_id,req.body.username,req.body.password])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}
pbkb.groupadd=function(req,res){
    if(wrong_args([req.body.user_id,req.body.session_id,req.body.groupname],'groupadd')){
        res.send('wrong_args of groupadd');
    }else{
        pbkb.log('call groupadd('+[req.body.user_id,req.body.session_id,req.body.groupname].join(',')+')');
        pbkb.pool.query("call groupadd(?,?,?)",[req.body.user_id,req.body.session_id,req.body.groupname])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}
pbkb.groupdel=function(req,res){
    if(wrong_args([req.body.user_id,req.body.session_id,req.body.groupname],'groupdel')){
        res.send('wrong_args of groupdel');
    }else{
        pbkb.log('call groupdel('+[req.body.user_id,req.body.session_id,req.body.groupname].join(',')+')');
        pbkb.pool.query("call groupdel(?,?,?)",[req.body.user_id,req.body.session_id,req.body.groupname])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}
pbkb.change_groupname=function(req,res){
    if(wrong_args([req.body.user_id,req.body.session_id,req.body.groupname,req.body.new_name],'change_groupname')){
        res.send('wrong_args of change_groupname');
    }else{
        pbkb.log('call change_groupname('+[req.body.user_id,req.body.session_id,req.body.groupname,req.body.new_name].join(',')+')');
        pbkb.pool.query("call change_groupname(?,?,?,?)",[req.body.user_id,req.body.session_id,req.body.groupname,req.body.new_name])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}
pbkb.groupquery=function(req,res){
    pbkb.pool.query("select group_id from groups where groupname=? limit 1",[req.body.groupname])
    .then(rows=>{
        res.type('json');
        res.send(rows);
    })
    .catch(pbkb.query_err);
}
pbkb.group_add_mem=function(req,res){
    if(wrong_args([req.body.user_id,req.body.session_id,req.body.groupname,req.body.group_uid],'group_add_mem')){
        res.send('wrong_args of group_add_mem');
    }else{
        pbkb.log('call group_add_mem('+[req.body.user_id,req.body.session_id,req.body.groupname,req.body.group_uid].join(',')+')');
        pbkb.pool.query("call group_add_mem(?,?,?,?)",[req.body.user_id,req.body.session_id,req.body.groupname,req.body.group_uid])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}
pbkb.group_del_mem=function(req,res){
    if(wrong_args([req.body.user_id,req.body.session_id,req.body.groupname,req.body.group_uid],'group_del_mem')){
        res.send('wrong_args of group_del_mem');
    }else{
        pbkb.log('call group_del_mem('+[req.body.user_id,req.body.session_id,req.body.groupname,req.body.group_uid].join(',')+')');
        pbkb.pool.query("call group_del_mem(?,?,?,?)",[req.body.user_id,req.body.session_id,req.body.groupname,req.body.group_uid])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}

pbkb.get_files=function (req,res){          // 用户被删除时,username返回null
    if(wrong_args([req.body.file_id,req.body.isdir,req.body.user_id,req.body.session_id],'get_files')){
        res.send('wrong_args of get_files');
    }else{
        pbkb.pool.query("call get_files(?,?,?,?)",[req.body.file_id,req.body.isdir,req.body.user_id,req.body.session_id])
        .then(rows=>{
            if(rows[0].status===0){         // 没有结果: file_id或isdir输入错误,或文件已被删除
                res.send('0');
            } else {
                res.type('json');
                res.send(rows[0]);
            }
        })
        .catch(pbkb.query_err);
    }
}

pbkb.mkdir=function (req,res){
    if(wrong_args([req.body.filename,req.body.pdir_id,req.body.user_id,req.body.session_id],'mkdir')){
        res.send('wrong_args of mkdir');
    }else{
        pbkb.log('call mkdir('+[req.body.filename,req.body.pdir_id,req.body.user_id,req.body.session_id].join(',')+')');
        pbkb.pool.query("call mkdir(?,?,?,?)",[req.body.filename,req.body.pdir_id,req.body.user_id,req.body.session_id])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}

pbkb.mkfile_pre=function(req,res){
    if(wrong_args([req.body.user_id,req.body.session_id,req.body.pdir_id],'mkfile_pre')){
        res.send('wrong_args of mkfile_pre');
    }else{
        pbkb.log('call mkfile_pre('+[req.body.user_id,req.body.session_id,req.body.pdir_id].join(',')+')');
        pbkb.pool.query("call mkfile_pre(?,?,?)",[req.body.user_id,req.body.session_id,req.body.pdir_id])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}
pbkb.mkfile=function(req,res){              // 因content的内容可能很多,因此不用pbkb.log()作记录
    if(wrong_args([req.body.user_id,req.body.file_id,req.body.filename,req.body.pdir_id,req.body.btime,req.body.content,req.body.text,req.body.session_id],'mkfile')){
        res.send('wrong_args of mkfile');
    }else{
        pbkb.pool.query("call mkfile(?,?,?,?,?,?,?,?)",[req.body.user_id,req.body.file_id,req.body.filename,req.body.pdir_id,req.body.btime,req.body.content,req.body.text,req.body.session_id])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
            // 移动到正式文件夹 并删除多余的临时文件
            var attachments_new=JSON.parse(req.body.attachments_new);                 // 前端将数组转换为字符串,故此处需将字符串还原为数组
            if(attachments_new.length>0){
                mkdir(pbkb.attached_path+'/'+req.body.year);
                mkdir(pbkb.attached_path+'/'+req.body.year+'/'+req.body.monthday);
                var attached_full_path=pbkb.attached_path+'/'+req.body.year+'/'+req.body.monthday+'/'+req.body.file_id;
                mkdir(attached_full_path);
                for (var i in attachments_new){
                    rename(req.body.attached_tmp_uid+'/'+attachments_new[i], attached_full_path+'/'+attachments_new[i]);
                }
            }
            rmdir(req.body.attached_tmp_uid);
        })
        .catch(pbkb.query_err);
    }
}

pbkb.button_editfile=function(req,res){
    if(wrong_args([req.body.file_id,req.body.user_id,req.body.session_id],'button_editfile')){
        res.send('wrong_args of button_editfile');
    }else{
        pbkb.pool.query("call button_editfile(?,?,?)",[req.body.file_id,req.body.user_id,req.body.session_id])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}
pbkb.editfile_pre=function(req,res){
    if(wrong_args([req.body.user_id,req.body.session_id,req.body.file_id],'editfile_pre')){
        res.send('wrong_args of editfile_pre');
    }else{
        pbkb.log('call editfile_pre('+[req.body.user_id,req.body.session_id,req.body.file_id].join(',')+')');
        pbkb.pool.query("call editfile_pre(?,?,?)",[req.body.user_id,req.body.session_id,req.body.file_id])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}
pbkb.editfile=function(req,res){            // 因content的内容可能很多,因此不用pbkb.log()作记录
    if(wrong_args([req.body.user_id,req.body.file_id,req.body.filename,req.body.content,req.body.text,req.body.session_id],'editfile')){
        res.send('wrong_args of editfile');
    }else{
        pbkb.pool.query("call editfile(?,?,?,?,?,?)",[req.body.user_id,req.body.file_id,req.body.filename,req.body.content,req.body.text,req.body.session_id])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
            // 处理附件
            var i;
            //pbkb.log('req.body.attachments_new: '+req.body.attachments_new);          // 若文件名带有中文，有时会变成URL编码，下面执行rename移动文件时就会出错
            //pbkb.log('req.body.attachments_old: '+req.body.attachments_old);
            var attachments_new=JSON.parse(req.body.attachments_new);                   // 前端将数组转换为字符串
            var attachments_old=JSON.parse(req.body.attachments_old);
            var attached_full_path=pbkb.attached_path+'/'+req.body.year+'/'+req.body.monthday+'/'+req.body.file_id;
            if(!fs.existsSync(attached_full_path) && attachments_new.length===0){       // 原来没有附件,也没有新的附件时,清理临时文件即可
                rmdir(req.body.attached_tmp_uid)
            } else if(!fs.existsSync(attached_full_path) && attachments_new.length>0){  // 原来没有附件,而有新的附件时
                mkdir(pbkb.attached_path+'/'+req.body.year);
                mkdir(pbkb.attached_path+'/'+req.body.year+'/'+req.body.monthday);
                mkdir(attached_full_path);
                for (i in attachments_new){
                    rename(req.body.attached_tmp_uid+'/'+attachments_new[i], attached_full_path+'/'+attachments_new[i]);
                }
                rmdir(req.body.attached_tmp_uid);
            } else {                        // 原来就有附件,隐含了条件 if(fs.existsSync(attached_full_path)); attachments_new.length<0也会归入这里,但不可能小于0
                if(attachments_new.length===0 && attachments_old.length===0){
                    // 删除了所有附件时
                    rmdir(req.body.attached_tmp_uid);
                    rmdir(attached_full_path);
                } else {
                    // 附件不为0时
                    //新建临时目录
                    var attached_full_path_tmp=pbkb.attached_path+'/'+req.body.year+'/'+req.body.monthday+'/'+req.body.file_id+'edit';
                    mkdir(attached_full_path_tmp);
                    //移动附件
                    for (i in attachments_new){
                        rename(req.body.attached_tmp_uid+'/'+attachments_new[i], attached_full_path_tmp+'/'+attachments_new[i]);
                    }
                    for (i in attachments_old){
                        rename(attached_full_path+'/'+attachments_old[i], attached_full_path_tmp+'/'+attachments_old[i]);
                    }
                    //删除多余的附件和目录
                    rmdir(req.body.attached_tmp_uid);
                    rmdir(attached_full_path);
                    //临时目录改名file_id
                    rename(attached_full_path_tmp, attached_full_path);
                }
            }
        })
        .catch(pbkb.query_err);
    }
}

pbkb.button_delfile=function(req,res){      // 浏览文件内容时的"删除文件"按钮
    if(wrong_args([req.body.user_id,req.body.session_id,req.body.file_id],'button_delfile')){
        res.send('wrong_args of button_delfile');
    }else{
        pbkb.log('call button_delfile('+[req.body.user_id,req.body.session_id,req.body.file_id].join(',')+')');
        pbkb.pool.query("call button_delfile(?,?,?)",[req.body.user_id,req.body.session_id,req.body.file_id])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
            if(rows[0][0].status===0) del_attachments(req.body.file_id,rows[0][0].btime);
        })
        .catch(pbkb.query_err);
    }
}

pbkb.save_editor_content=function(req,res){
    if(wrong_args([req.body.user_id,req.body.session_id,req.body.filename,req.body.file_id,req.body.pdir_id,req.body.content],'save_editor_content')){
        res.send('wrong_args of save_editor_content');
    }else{
        pbkb.pool.query("call save_editor_content(?,?,?,?,?,?)",[req.body.user_id,req.body.session_id,req.body.filename,req.body.file_id,req.body.pdir_id,req.body.content])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}

pbkb.del_editor_content=function(req,res){  // 清理 新建文件 或 编辑文件 时产生的临时文件
    if(wrong_args([req.body.user_id,req.body.session_id],'del_editor_content')){
        res.send('wrong_args of del_editor_content');
    }else{
        pbkb.log('取消编辑文件或新建文件: call del_editor_content('+[req.body.user_id,req.body.session_id].join(',')+')');
        pbkb.pool.query("call del_editor_content(?,?)",[req.body.user_id,req.body.session_id])
        .then(rows=>{
            res.send('1');
        })
        .catch(pbkb.query_err);
        rmdir(req.body.attached_tmp_uid);
    }
}

pbkb.del_cfile=function(req,res){           // 目录文件清单中的"删除"按钮
    if(wrong_args([req.body.user_id,req.body.session_id,req.body.file_id],'del_cfile')){
        res.send('wrong_args of del_cfile');
    }else{
        pbkb.log('call del_cfile('+[req.body.user_id,req.body.session_id,req.body.file_id].join(',')+')');
        pbkb.pool.query("call del_cfile(?,?,?)",[req.body.user_id,req.body.session_id,req.body.file_id])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
            del_attachments(req.body.file_id,rows[0][0].btime);
        })
        .catch(pbkb.query_err);
    }
}

pbkb.movedir=function(req,res){
    if(wrong_args([req.body.user_id,req.body.session_id,req.body.from,req.body.to],'movedir')){
        res.send('wrong_args of movedir');
    }else{
        pbkb.log('call movedir('+[req.body.user_id,req.body.session_id,req.body.from,req.body.to].join(',')+')');
        pbkb.pool.query("call movedir(?,?,?,?)",[req.body.user_id,req.body.session_id,req.body.from,req.body.to])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}

pbkb.re_name=function(req,res){
    if(wrong_args([req.body.user_id,req.body.session_id,req.body.file_id,req.body.name],'re_name')){
        res.send('wrong_args of re_name');
    }else{
        pbkb.log('call re_name('+[req.body.user_id,req.body.session_id,req.body.file_id,req.body.name].join(',')+')');
        pbkb.pool.query("call re_name(?,?,?,?)",[req.body.user_id,req.body.session_id,req.body.file_id,req.body.name])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}

pbkb.toggle_top=function(req,res){
    if(wrong_args([req.body.user_id,req.body.session_id,req.body.file_id,req.body.istop],'toggle_top')){
        res.send('wrong_args of toggle_top');
    }else{
        pbkb.log('call toggle_top('+[req.body.user_id,req.body.session_id,req.body.file_id,req.body.istop].join(',')+')');
        pbkb.pool.query("call toggle_top(?,?,?,?)",[req.body.user_id,req.body.session_id,req.body.file_id,req.body.istop])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}

pbkb.toggle_pri=function(req,res){
    if(wrong_args([req.body.user_id,req.body.session_id,req.body.file_id,req.body.hidden],'toggle_pri')){
        res.send('wrong_args of toggle_pri');
    }else{
        pbkb.log('call toggle_pri('+[req.body.user_id,req.body.session_id,req.body.file_id,req.body.hidden].join(',')+')');
        pbkb.pool.query("call toggle_pri(?,?,?,?)",[req.body.user_id,req.body.session_id,req.body.file_id,req.body.hidden])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}

pbkb.get_groups=function(req,res){
    pbkb.pool.query("select group_id,groupname from groups order by group_id")
    .then(rows=>{
        res.type('json');
        res.send(rows);
    })
    .catch(pbkb.query_err);
}

pbkb.change_group_OK=function(req,res){
    if(wrong_args([req.body.user_id,req.body.session_id,req.body.file_id,req.body.group_id],'change_group_OK')){
        res.send('wrong_args of change_group_OK');
    }else{
        pbkb.log('call change_group('+[req.body.user_id,req.body.session_id,req.body.file_id,req.body.group_id].join(',')+')');
        pbkb.pool.query("call change_group(?,?,?,?)",[req.body.user_id,req.body.session_id,req.body.file_id,req.body.group_id])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}

pbkb.get_group_id=function(req,res){
    pbkb.pool.query("select group_id from files where file_id=? limit 1",[req.body.file_id])
    .then(rows=>{
        res.type('json');
        res.send(rows);
    })
    .catch(pbkb.query_err);
}

pbkb.get_full_path=function(req,res){
    if(wrong_args([req.body.file_id],'get_full_path')){
        res.send('wrong_args of get_full_path');
    }else{
        pbkb.pool.query("call get_full_path(?)",[req.body.file_id])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}

pbkb.get_filename=function(req,res){
    pbkb.pool.query("select filename from files where file_id=? limit 1",[req.body.file_id])
    .then(rows=>{
        res.type('json');
        res.send(rows);
    })
    .catch(pbkb.query_err);
}

pbkb.search_all_filename=function(req,res){
    if(wrong_args(['%'+req.body.search+'%',req.body.user_id,req.body.session_id],'search_all_filename')){
        res.send('wrong_args of search_all_filename');
    }else{
        pbkb.log('saf,在所有目录搜索文件名: '+req.body.search);
        pbkb.pool.query("call search_all_filename(?,?,?)",['%'+req.body.search+'%',req.body.user_id,req.body.session_id])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}

pbkb.search_all_content=function(req,res){
    if(wrong_args(['%'+req.body.search+'%',req.body.user_id,req.body.session_id],'search_all_content')){
        res.send('wrong_args of search_all_content');
    }else{
        pbkb.log('sac,在所有目录搜索文件内容: '+req.body.search);
        pbkb.pool.query("call search_all_content(?,?,?)",['%'+req.body.search+'%',req.body.user_id,req.body.session_id])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}

pbkb.search_cur_filename=function(req,res){
    if(wrong_args([req.body.file_id,'%'+req.body.search+'%',req.body.user_id,req.body.session_id],'search_cur_filename')){
        res.send('wrong_args of search_cur_filename');
    }else{
        pbkb.log('scf,在file_id为 '+req.body.file_id+' 的目录及子目录搜索文件名: '+req.body.search);
        pbkb.pool.query("call search_cur_filename(?,?,?,?)",[req.body.file_id,'%'+req.body.search+'%',req.body.user_id,req.body.session_id])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}

pbkb.search_cur_content=function(req,res){
    if(wrong_args([req.body.file_id,'%'+req.body.search+'%',req.body.user_id,req.body.session_id],'search_cur_content')){
        res.send('wrong_args of search_cur_content');
    }else{
        pbkb.log('scc,在file_id为 '+req.body.file_id+' 的目录及子目录搜索文件内容: '+req.body.search);
        pbkb.pool.query("call search_cur_content(?,?,?,?)",[req.body.file_id,'%'+req.body.search+'%',req.body.user_id,req.body.session_id])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}

pbkb.recover_tmp=function(req,res){
    if(wrong_args([req.body.user_id,req.body.session_id],'recover_tmp')){
        res.send('wrong_args of recover_tmp');
    }else{
        pbkb.log('call recover_tmp('+[req.body.user_id,req.body.session_id].join(',')+')');
        pbkb.pool.query("call recover_tmp(?,?)",[req.body.user_id,req.body.session_id])
        .then(rows=>{
            res.type('json');
            res.send(rows[0]);
        })
        .catch(pbkb.query_err);
    }
}

module.exports = pbkb;
